using UnityEngine;
using System;
using System.Collections;
using System.Runtime.InteropServices;
using System.Collections.Generic;


[ StructLayout( LayoutKind.Sequential , Pack = 1 ) ]
public class SABattleResult
{
	public byte cmdtype;

	public byte atkNum = 0;
	public byte defNum = 0;
	
	public byte atkSide;

	public byte[] atkRow = null;
	public byte[] atkIndex = null;

	public byte defSide;

	public byte[] defRow = null;
	public byte[] defIndex = null;

	public byte[] resultType = null;
	public short[] resultHP = null;
}



public enum SABattleResultStageType
{
	MOVETO_ATTACK = 0,
	ACTION_ATTACK,
	MOVEBACK_ATTACK,
	
	DEF,
	DEF_BACK,

	ACTION_HURT,
	MOVEBACK_HURT,

	COUNT
}


public struct SABattleResultCreatureStage
{
	public int stageType;
	public int attackCount;

	public bool playOver;


}

public class SABattleResultManager : Singleton< SABattleResultManager > 
{
	void Awake ()
	{
		mInstance = this;
		
	}

	[ HideInInspector ] public byte turn;
	[ HideInInspector ] public byte result;
	[ HideInInspector ] public byte num;

	[ HideInInspector ] public SABattleResult[] battleResults = null;
	[ HideInInspector ] public SABattleResult activeResult = null;
	[ HideInInspector ] public int activeResultIndex = GameDefine.INVALID_ID;


	private Dictionary< GameObject , SABattleResultCreatureStage > creatureStage = new Dictionary< GameObject , SABattleResultCreatureStage >();

	public void clear()
	{
		turn = 0;
		result = 0;
		num = 0;

		battleResults = null;
		activeResult = null;
		activeResultIndex = GameDefine.INVALID_ID;

		creatureStage.Clear();
	}

	void checkResult()
	{
		foreach ( KeyValuePair< GameObject , SABattleResultCreatureStage > pair in creatureStage )
		{
			if ( !pair.Value.playOver )
			{
				return;
			}
		}

		playNextResult();
	}

	void playNextResult()
	{
		activeResultIndex++;

		if ( activeResultIndex >= battleResults.Length ) 
		{
			if ( result == (int)SABattleResultType.WIN || 
			    result == (int)SABattleResultType.LOSE )
			{
				LoadingUIHandler.instance.Show();
				LoadingUIHandler.instance.loadScene( 1 );
			}
			else
			{
				SABattleManager.instance.changeContralStage( (int)SABattleContralStage.COMMAND );

			}

			return;
		}

		activeResult = battleResults[ activeResultIndex ];

		creatureStage.Clear();

		switch ( activeResult.cmdtype ) 
		{
		case (byte)SABattleSessionCommandType.ATTACK:

			if ( activeResult.defNum == 1 )  
			{
				GameObject objDef = SABattleCreautreManager.instance.getCreature( activeResult.defSide , activeResult.defRow[ 0 ] , activeResult.defIndex[ 0 ] );
				SABattleCreature creatureDef = objDef.GetComponent< SABattleCreature >();
				SABattlePos posAdvanceDef = creatureDef.getAdvancePos();

				for ( int i = 0 ; i < activeResult.atkNum ; i++ )
				{
					SABattleResultCreatureStage stage = new SABattleResultCreatureStage();
					stage.stageType = (int)SABattleResultStageType.MOVETO_ATTACK;
					stage.playOver = false;

					GameObject obj = SABattleCreautreManager.instance.getCreature( activeResult.atkSide , activeResult.atkRow[ i ] , activeResult.atkIndex[ i ] );
					creatureStage[ obj ] = stage;
					
					SABattleCreature creature = obj.GetComponent< SABattleCreature >();
					creature.startMove( posAdvanceDef.x , posAdvanceDef.y , -0.2f * ( i ) );
				}


			}
			else
			{

			}

			for ( int i = 0 ; i < activeResult.defNum ; i++ )
			{
				SABattleResultCreatureStage stage = new SABattleResultCreatureStage();
				stage.stageType = (int)SABattleResultStageType.COUNT;
				stage.attackCount = 0;
				stage.playOver = false;
				
				GameObject obj = SABattleCreautreManager.instance.getCreature( activeResult.defSide , activeResult.defRow[ i ] , activeResult.defIndex[ i ] );
				creatureStage[ obj ] = stage;
				
				SABattleCreature creature = obj.GetComponent< SABattleCreature >();
				
				if ( activeResult.resultType[ i ] == (int)SABattleSessionResultType.KILL ) 
				{
					creature.normalStatus = (int)SANormalStatusType.FALL;
				}
			}
			
			break;
		case (byte)SABattleSessionCommandType.DEFENCE:
			for ( int i = 0; i < activeResult.atkNum ; i++ )
			{
				SABattleResultCreatureStage stage = new SABattleResultCreatureStage();
				stage.stageType = (int)SABattleResultStageType.COUNT;
				stage.attackCount = 0;
				stage.playOver = true;

				GameObject obj = SABattleCreautreManager.instance.getCreature( activeResult.atkSide , activeResult.atkRow[ i ] , activeResult.atkIndex[ i ] );
				creatureStage[ obj ] = stage;

				SABattleCreature creature = obj.GetComponent< SABattleCreature >();
				creature.setAction( (int)SAActionType.DEFENCE );
				creature.normalStatus = (int)SANormalStatusType.DEFENCE;
			}
			playNextResult();
			break;
		case (byte)SABattleSessionCommandType.ESCAPE:

			LoadingUIHandler.instance.Show();
			LoadingUIHandler.instance.loadScene( 1 );
			break;
		}


	}

	public void playResult( byte t , byte r , byte n , byte[] d )
	{
		turn = t;
		result = r;
		num = n;

		battleResults = new SABattleResult[ num ];
		activeResultIndex = GameDefine.INVALID_ID;

		int index = 0;
		for ( int i = 0 ; i < num ; i++ ) 
		{
			SABattleResult result1 = new SABattleResult();

			result1.cmdtype = d[ index ]; index++;
			result1.atkSide = d[ index ]; index++;

			battleResults[ i ] = result1;

			switch ( result1.cmdtype )  
			{
			case (byte)SABattleSessionCommandType.ATTACK:

				result1.defSide = d[ index ]; index++;

				result1.atkNum = d[ index ]; index++;
				result1.defNum = d[ index ]; index++;

				result1.atkRow = new byte[ result1.atkNum ];
				result1.atkIndex = new byte[ result1.atkNum ];

				result1.defRow = new byte[ result1.defNum ];
				result1.defIndex = new byte[ result1.defNum ];
				result1.resultType = new byte[ result1.defNum ];
				result1.resultHP = new short[ result1.defNum ];

				for ( int j = 0; j < result1.atkNum ; j++ )
				{
					result1.atkRow[ j ] = d[ index ]; index++;
					result1.atkIndex[ j ] = d[ index ]; index++;
				}

				for ( int j = 0; j < result1.defNum ; j++ )
				{
					result1.defRow[ j ] = d[ index ]; index++;
					result1.defIndex[ j ] = d[ index ]; index++;

					result1.resultType[ j ] = d[ index ]; index++;
					result1.resultHP[ j ] = BitConverter.ToInt16( d , index ); index += 2;
				}

				break;
				
			case (byte)SABattleSessionCommandType.DEFENCE:
				result1.atkNum = 1;
				result1.atkRow = new byte[ 1 ];
				result1.atkIndex = new byte[ 1 ];

				result1.atkRow[ 0 ] = d[ index ]; index++;
				result1.atkIndex[ 0 ] = d[ index ]; index++;
				break;
				
			case (byte)SABattleSessionCommandType.MAGIC:
				break;
				
			case (byte)SABattleSessionCommandType.STAY:
				break;

			case (byte)SABattleSessionCommandType.ESCAPE:
				result1.atkNum = 1;
				result1.atkRow = new byte[ 1 ];
				result1.atkIndex = new byte[ 1 ];
				
				result1.atkRow[ 0 ] = d[ index ]; index++;
				result1.atkIndex[ 0 ] = d[ index ]; index++;
				break;
			}
		}

		SABattleManager.instance.changeContralStage( (int)SABattleContralStage.RESULT );

		playNextResult();
	}


	public void onActionOver( SABattleCreature c , int a )
	{
		if ( !creatureStage.ContainsKey( c.gameObject ) ) 
		{
			// meybe from the previous turn,,
			return;
		}

		SABattleResultCreatureStage stage = creatureStage[ c.gameObject ];
		
		switch ( stage.stageType ) 
		{
		case (int)SABattleResultStageType.ACTION_ATTACK:

			if ( a != (int)SAActionType.ATTACK ) 
			{
				return;
			}

			stage.stageType = (int)SABattleResultStageType.MOVEBACK_ATTACK;
			SABattlePos pos = c.getOriginalPos();
			c.setDirection( c.getReverseOriginalDirection() );
			c.startMove( pos.x , pos.y , 0.0f );

			for ( int i = 0 ; i < activeResult.defNum ; i++ ) 
			{
				GameObject obj = SABattleCreautreManager.instance.getCreature( activeResult.defSide , activeResult.defRow[ i ] , activeResult.defIndex[ i ] );
				
				SABattleCreature creature = obj.GetComponent< SABattleCreature >();

				SABattleResultCreatureStage stage1 = creatureStage[ obj ];

				stage1.attackCount++;

				if ( stage1.attackCount == activeResult.atkNum ) 
				{
					stage1.stageType = (int)SABattleResultStageType.MOVEBACK_HURT;
					SABattlePos pos1 = creature.getOriginalPos();
					creature.startMove( pos1.x , pos1.y , 0.0f , creature.normalStatus != (int)SANormalStatusType.DEFENCE );
				}

				creatureStage[ obj ] = stage1;
			}

			break;
		case (int)SABattleResultStageType.ACTION_HURT:


			break;
		}

		creatureStage[ c.gameObject ] = stage;
	}

	public void onMoveOver( SABattleCreature c )
	{
		SABattleResultCreatureStage stage = creatureStage[ c.gameObject ];

		switch ( stage.stageType ) 
		{
		case (int)SABattleResultStageType.MOVETO_ATTACK:
			stage.stageType = (int)SABattleResultStageType.ACTION_ATTACK;

			c.setAction( (int)SAActionType.ATTACK );

			for ( int i = 0 ; i < activeResult.defNum ; i++ ) 
			{
				GameObject obj = SABattleCreautreManager.instance.getCreature( activeResult.defSide , activeResult.defRow[ i ] , activeResult.defIndex[ i ] );
				
				SABattleCreature creature = obj.GetComponent< SABattleCreature >();
				

				SABattleResultCreatureStage stage1 = creatureStage[ obj ];
				stage1.stageType = (int)SABattleResultStageType.ACTION_HURT;

				if ( stage1.attackCount == 0 )
				{
					SABattlePos pos = creature.getBackPos();
					creature.startMove( pos.x , pos.y , 0.0f , false );
					creature.setMoveSpeed( GameDefine.DEFAULT_BATTLE_MOVE_SPEED1 );
				}

				if ( creature.normalStatus != (int)SANormalStatusType.DEFENCE )
				{
					creature.setAction( (int)SAActionType.HURT );
				}

				creatureStage[ obj ] = stage1;
			}

			break;
		case (int)SABattleResultStageType.MOVEBACK_ATTACK:
			stage.stageType = (int)SABattleResultStageType.COUNT;
			stage.playOver = true;
			c.setAction( (int)SAActionType.STAND , c.getOriginalDirection() );

			break;

		case (int)SABattleResultStageType.MOVEBACK_HURT:
			stage.stageType = (int)SABattleResultStageType.COUNT;
			stage.playOver = true;

			c.setAction( c.normalStatus == (int)SANormalStatusType.FALL ? (int)SAActionType.FALL : (int)SAActionType.STAND , c.getOriginalDirection() );
			c.setMoveSpeed( GameDefine.DEFAULT_BATTLE_MOVE_SPEED );

			break;


		}

		creatureStage[ c.gameObject ] = stage;

		checkResult();
	}

	void Update()
	{
	}


}

